package com.swotxu.screwweb.util;

import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.SAXSource;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.io.StringBufferInputStream;

/**
 * @Date: 2021/7/13 9:54
 * @Author: xu.hai
 */
public abstract class XmlConfigUtils {

    private static final Logger log = LoggerFactory.getLogger(XmlConfigUtils.class);

    public static <T> T xml2bean(Class<T> cls, String filePath) {
        try {
            File file = new File(filePath);
            if (!file.exists()) {
                log.error("pubsub-xml2bean fail, file not found!, filePath:{}", filePath);
                return null;
            }

            // 构造 EntityResolver，忽略 dtd校验
            EntityResolver ignoreDTDEntityResolver = (publicId, systemId) -> new InputSource(new StringBufferInputStream(""));
            // 设置 EntityResolver
            XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
            xmlReader.setEntityResolver(ignoreDTDEntityResolver);
            // 获取 xml文件
            InputSource inputSource = new InputSource(new FileReader(filePath));

            Unmarshaller unmar = JAXBContext.newInstance(cls).createUnmarshaller();

            Object obj = unmar.unmarshal(new SAXSource(xmlReader, inputSource));
            if (obj != null) {
                return (T) obj;
            }
        } catch (Exception e) {
            log.error("pubsub-xml2bean fail, filePath: " + filePath, e);
        }
        return null;
    }

    public static <T> T xml2bean(Class<T> cls, InputStream inputStream) {
        if (null == inputStream) {
            log.error("pubsub-xml2bean fail, inputStream is null");
            return null;
        }
        try {
            Unmarshaller unmar = JAXBContext.newInstance(new Class[]{cls}).createUnmarshaller();
            return (T) unmar.unmarshal(inputStream);
        } catch (JAXBException e) {
            log.error("pubsub-xml2bean fail, inputStream error", e);
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
        return null;
    }
}
